package tw.com.hitevision.whiteboard.android.widgets;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;

import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import tw.com.hitevision.whiteboard.android.R;

public class ImageViewAdapter extends RecyclerView.Adapter<ImageViewAdapter.ImageViewHolder> {
    private static final String TAG = ImageViewAdapter.class.getSimpleName();
    private static final int INVALID_VALUE = -1;
    private List<String> dataSet;
    private List<float[]> imageInfoSet;
    private Context context;
    private int focusedItemId;
    private ImageClickListener imageClickLis;
    private float dx, dy;
    private int currentSelectedIndex;
    //    private Picasso picasso;
    private boolean dragged;

    private int childOverrideW;
    private RequestOptions requestOptions;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class ImageViewHolder extends RecyclerView.ViewHolder {
        public ImageView image;
        public ImageView addButton;
        public ImageView frame;
        public ProgressBar progressBar;
        public TextView imageSizeInfo;

        @SuppressLint("ClickableViewAccessibility")
        public ImageViewHolder(View v) {
            super(v);
            image = v.findViewById(R.id.child_image);
            addButton = v.findViewById(R.id.add_Button);
            addButton.setVisibility(View.GONE);
            frame = v.findViewById(R.id.frame);
            frame.setVisibility(View.GONE);
            progressBar = v.findViewById(R.id.child_progress_bar);
            imageSizeInfo = v.findViewById(R.id.image_info);
            imageSizeInfo.setPadding(0, 0, 0, 2);

            childOverrideW = (int) context.getResources().getDimension(R.dimen.search_image_view_child_width);

            requestOptions = new RequestOptions();
            requestOptions.placeholder(null);
            requestOptions.fitCenter();
            requestOptions.error(R.drawable.ic_close);
            requestOptions.downsample(DownsampleStrategy.CENTER_INSIDE);
            requestOptions.fitCenter();
            requestOptions.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC);

            image.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    final int index = event.getActionIndex();
                    final int pointer = event.getPointerId(index);

                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                        case MotionEvent.ACTION_POINTER_DOWN: {
                            if (pointer != 0) {
                                return false;
                            }
                            imageClickLis.disableDragging(false);
                            imageClickLis.setPreview(image);
                            imageClickLis.hideKeyBoardFromAdapter();
                            dx = event.getX() - image.getX();
                            dy = event.getY() - image.getY();
                            dragged = false;
                            break;
                        }
                        case MotionEvent.ACTION_MOVE: {
                            if (pointer != 0) {
                                return false;
                            }
                            if (addButton.getVisibility() == View.VISIBLE) {
                                if (image.getVisibility() == View.VISIBLE) {
                                    image.setVisibility(View.INVISIBLE);
                                }
                                imageClickLis.disableDragging(true);
                                imageClickLis.movePreview(image, itemView.getX() + event.getX() - dx, itemView.getY() + event.getY() - dy);
                                dragged = true;
                            }
                            break;
                        }
                        case MotionEvent.ACTION_UP:
                        case MotionEvent.ACTION_POINTER_UP: {
                            if (pointer != 0) {
                                return false;
                            }
                            imageClickLis.setPreview(null);

                            if (image.getVisibility() != View.VISIBLE) {
                                image.setVisibility(View.VISIBLE);
                            }

                            int oldId = currentSelectedIndex;

                            if (addButton.getVisibility() != View.VISIBLE) {
                                currentSelectedIndex = getAdapterPosition();
                            } else {
                                if (!dragged) {
                                    currentSelectedIndex = INVALID_VALUE;
                                }

                                Drawable d = image.getDrawable();

                                if (d == null || d.getIntrinsicWidth() <= 0 || d.getIntrinsicHeight() <= 0) {
                                    return false;
                                }

                                float offsetX = 0;
                                float offsetY = 0;
                                if (d.getIntrinsicWidth() > image.getWidth()) {
                                    float childImageHeight = (float) d.getIntrinsicHeight() * ((float) image.getWidth() / (float) d.getIntrinsicWidth());
                                    offsetY = (image.getHeight() - childImageHeight) / 2;
                                } else {
                                    offsetX = (image.getWidth() - d.getIntrinsicWidth()) / 2;
                                }

                                imageClickLis.createImageByDragging(image, getAdapterPosition(),
                                        itemView.getX() + event.getX() - dx + offsetX, itemView.getY() + event.getY() - dy + offsetY);
                            }

                            notifyItemChanged(oldId);

                            if (currentSelectedIndex != INVALID_VALUE && currentSelectedIndex != oldId) {
                                notifyItemChanged(currentSelectedIndex);
                            }
                            break;
                        }
                    }
                    return false;
                }
            });

            addButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (v.getVisibility() == View.VISIBLE) {
                        focusedItemId = getLayoutPosition();
                        notifyItemChanged(focusedItemId);
                        if (imageClickLis != null) {
                            imageClickLis.createImageByClick(image, getAdapterPosition());
                        }
                    }
                }
            });
        }

    }

    @Override
    public void onViewRecycled(@NonNull ImageViewHolder holder) {
        super.onViewRecycled(holder);
//        picasso.cancelRequest(holder.image);
//        Glide.with(context)
//                .clear(holder.image);
//        holder.image.setImageDrawable(null);
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public ImageViewAdapter(List<String> dataSet, List<float[]> info, Context context, ImageClickListener lis) {
        this.dataSet = dataSet;
        this.imageInfoSet = info;
        this.context = context;
        this.imageClickLis = lis;
        currentSelectedIndex = INVALID_VALUE;

//        OkHttpClient okHttpClient = new OkHttpClient.Builder()
//                .connectTimeout(1, TimeUnit.SECONDS)
//                .writeTimeout(1, TimeUnit.SECONDS)
//                .readTimeout(1, TimeUnit.SECONDS)
//                .build();
//        picasso = new Picasso.Builder(context)
//                .downloader(new OkHttp3Downloader(okHttpClient))
//                .build();
    }

    // Create new views (invoked by the layout manager)
    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_search_child, parent, false);
        v.invalidate();

        ImageViewHolder holder = new ImageViewHolder(v);

        return holder;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ImageViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        // get bitmap from dataSet[position]

//        picasso.get()
//                .load(dataSet.get(position))
//                .error(R.drawable.draw_red)
//                .into(holder.image, new Callback() {
//                    @Override
//                    public void onSuccess() {
//                        holder.progressBar.setVisibility(View.GONE);
//                    }
//
//                    @Override
//                    public void onError(Exception e) {
//                        // set error image here
//                    }
//                });

//        RequestOptions requestOptions = new RequestOptions();
//        requestOptions.placeholder(null);
//        requestOptions.fitCenter();
//        requestOptions.error(R.drawable.ic_close);
//        requestOptions.downsample(DownsampleStrategy.CENTER_INSIDE);
////        requestOptions.encodeQuality(100);
////        requestOptions.override(200);
//        requestOptions.fitCenter();
//        requestOptions.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC);

        Glide.with(context)
                .load(dataSet.get(position))
                .apply(requestOptions)
                .override(childOverrideW, childOverrideW)
                .transition(DrawableTransitionOptions.withCrossFade())
                .encodeQuality(50)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        // set error image here
                        holder.addButton.setVisibility(View.GONE);
                        holder.frame.setVisibility(View.GONE);
                        holder.imageSizeInfo.setVisibility(View.GONE);
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        if (position == currentSelectedIndex) {
//                            hideItem(true);
                            holder.addButton.setVisibility(View.VISIBLE);
                            holder.frame.setVisibility(View.VISIBLE);
                            holder.imageSizeInfo.setVisibility(View.VISIBLE);
                            if (imageInfoSet != null && position < imageInfoSet.size() && imageInfoSet.get(position) != null) {
                                int w = (int) imageInfoSet.get(position)[0];
                                int h = (int) imageInfoSet.get(position)[1];
                                holder.imageSizeInfo.setText(w + " x " + h);
                            }
                        } else {
//                            hideItem(true);
                            holder.addButton.setVisibility(View.GONE);
                            holder.frame.setVisibility(View.GONE);
                            holder.imageSizeInfo.setVisibility(View.GONE);
                        }
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }
                })
                .into(holder.image);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return dataSet.size();
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public void resetCurrentSelectedIndex() {
        currentSelectedIndex = INVALID_VALUE;
    }

    private void log(String str) {
        Log.d(TAG, str);
    }

    public interface ImageClickListener {
        void createImageByClick(ImageView v, int id);

        void createImageByDragging(ImageView v, int id, float x, float y);

        void hideKeyBoardFromAdapter();

        void disableDragging(boolean disable);

        void setPreview(ImageView v);

        void movePreview(ImageView v, float x, float y);
    }
}